package fox.framework.rpc.endpoint.netty.client;

import fox.framework.rpc.client.message.response.ByteSourceResponseEntity;
import fox.framework.rpc.client.message.response.RpcClientResponse;
import fox.framework.rpc.client.message.response.RpcClientResponseBuilder;
import fox.framework.rpc.endpoint.exchange.RpcExchange;
import fox.framework.rpc.exception.RpcDecodeWithProtocolException;
import fox.framework.rpc.exception.RpcDecodeWithRequestIdException;
import fox.framework.rpc.exception.RpcRecordException;
import fox.framework.rpc.message.RpcHeader;
import fox.framework.rpc.message.RpcMessageStatus;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * @author cuichao
 * @Description: RpcClientResponseHandler
 * @Date: create in 2021/1/23 15:56
 */

@ChannelHandler.Sharable
public class RpcClientResponseHandler extends SimpleChannelInboundHandler<RpcClientResponse> {

    private RpcExchange exchange;



    public RpcClientResponseHandler(RpcExchange exchange) {
        this.exchange = exchange;
    }


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcClientResponse response) throws Exception {
        exchange.exchange(response);
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("client:"+cause.getClass());
        if (cause instanceof RpcRecordException) {
            cause.printStackTrace();
        } else if (cause instanceof RpcDecodeWithProtocolException) {
            RpcClientResponse response = buildExceptionResponse((RpcDecodeWithProtocolException) cause);
            exchange.exchange(response);
        } else {
            cause.printStackTrace();
        }
    }


    private RpcClientResponse buildExceptionResponse(RpcDecodeWithProtocolException exception) {
        byte[] bytesSource = exception.getMessage().getBytes();
        String ContentLength = Integer.toString(bytesSource.length);
        RpcClientResponseBuilder builder = new RpcClientResponseBuilder();
        builder.setStatus(RpcMessageStatus.COMMON_EXCEPTION_CODE);
        builder.setProtocol(exception.getProtocol());
        builder.setHeader(RpcHeader.CONTENT_LENGTH, ContentLength);
        builder.setHeader(RpcHeader.CONTENT_TYPE, RpcMessageStatus.COMMON_EXCEPTION_TYPE);
        builder.setResponseEntity(new ByteSourceResponseEntity(exception.getMessage().getBytes(), RpcMessageStatus.COMMON_EXCEPTION_CODE));
        if (exception instanceof RpcDecodeWithRequestIdException) {
            builder.setHeader(RpcHeader.REQUEST_ID, ((RpcDecodeWithRequestIdException) exception).getRequestId());
        }
        RpcClientResponse response = builder.build();
        return response;
    }

}
